package cn.junki;

import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

/**
 * Synchronized锁升级案例
 *
 * @author Junki
 * @date 2023-10-31 15:01:03
 */
public class Demo {

    public final Object lock = new Object();

    public void syncFun() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + "同步代码块中");
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    }


    public static void main(String[] args) throws Exception {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("等待5秒");

        Demo demo = new Demo();

        System.out.println(ClassLayout.parseInstance(demo.lock).toPrintable());

        // 加入一个子线程，并执行完毕
        Thread thread1 = new Thread(demo::syncFun);
        thread1.setName("子线程1");
        thread1.start();
        thread1.join();

        // 启动一个子线程
        Thread thread2 = new Thread(demo::syncFun);
        thread2.setName("子线程2");
        thread2.start();
        thread2.join();

        // 再启动一个子线程
        Thread thread3 = new Thread(demo::syncFun);
        thread3.setName("子线程3");
        thread3.start();
        thread3.join();

        TimeUnit.SECONDS.sleep(5);
        System.out.println("等待5秒");

        System.out.println(ClassLayout.parseInstance(demo.lock).toPrintable());
    }

    // 偏向锁 -> 轻量级锁
    private static void test4() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("等待5秒");

        Demo demo = new Demo();

        System.out.println(ClassLayout.parseInstance(demo.lock).toPrintable());

        // 加入一个子线程，并执行完毕
        Thread thread1 = new Thread(demo::syncFun);
        thread1.setName("子线程1");
        thread1.start();
        thread1.join();

        // 再加入一个子线程，并执行完毕
        Thread thread2 = new Thread(demo::syncFun);
        thread2.setName("子线程2");
        thread2.start();
        thread2.join();

        System.out.println(ClassLayout.parseInstance(demo.lock).toPrintable());
    }

    // 无锁 -> 偏向锁
    private static void test3() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("等待5秒");

        Demo demo = new Demo();

        System.out.println(ClassLayout.parseInstance(demo.lock).toPrintable());

        // 加入一个子线程，并执行完毕
        Thread thread = new Thread(demo::syncFun);
        thread.start();
        thread.join();

        System.out.println(ClassLayout.parseInstance(demo.lock).toPrintable());
    }

    // 无锁 -> 匿名偏向锁
    private static void test2() throws InterruptedException {
        System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());

        TimeUnit.SECONDS.sleep(5);
        System.out.println("等待5秒");

        System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
    }

    // 打印对象的内存布局信息
    private static void test1() {
        System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
    }

}
